﻿#region zh-CHS 2006 - 2010 DemoSoft 团队 | en 2006-2010 DemoSoft Team

//     NOTES
// ---------------
//
// This file is a part of the MMOSE(Massively Multiplayer Online Server Engine) for .NET.
//
//                              2006-2010 DemoSoft Team
//
//
// First Version : by H.Q.Cai - mailto:caihuanqing@hotmail.com

/***************************************************************************
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as published
 *   by the Free Software Foundation; either version 2.1 of the License, or
 *   (at your option) any later version.
 *
 ***************************************************************************/

#region zh-CHS 包含名字空间 | en Include namespace
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Demo.Mmose.Core.Common;
using Demo.Mmose.Core.Entity.Creature;
using Demo.Mmose.Core.Common.SafeCollections;
using System.Threading;
using Demo.Mmose.Core.Util;
#endregion

namespace Demo.Mmose.Core.Entity.Suit.Spell
{
    /// <summary>
    /// FIFO 先入先出
    /// </summary>
    public class AuraCollection
    {
        #region zh-CHS 构造和初始化和清理 | en Constructors and Initializers and Dispose
        /// <summary>
        /// 
        /// </summary>
        /// <param name="iCapacity"></param>
        public AuraCollection()
        {

        }

        /// <summary>
        /// 
        /// </summary>
        public AuraCollection( long serial )
        {
            m_Serial = serial;
        }
        #endregion

        #region zh-CHS 共有属性 | en Public Properties

        #region zh-CHS Serial属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private Serial m_Serial = Serial.Zero;
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public Serial Serial
        {
            get { return m_Serial; }
            set { m_Serial = value; }
        }

        #endregion

        #region zh-CHS Owner属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private Unit m_Owner = null;
        #endregion
        /// <summary>
        /// 拥有者的对象
        /// </summary>
        public Unit Owner
        {
            get { return m_Owner; }
            set { m_Owner = value; }
        }

        #endregion

        #region zh-CHS MaxAllInOneQueues属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private int m_MaxAllInOneQueues = int.MaxValue;
        #endregion
        /// <summary>
        /// 最大的队列
        /// </summary>
        public int MaxAllInOneQueues
        {
            get { return m_MaxAllInOneQueues; }
            set
            {
                if ( value < 0 )
                    return;
                else
                    m_MaxAllInOneQueues = value;
            }
        }

        #endregion

        #region zh-CHS MaxEnhanceQueues属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private int m_MaxEnhanceQueues = int.MaxValue;
        #endregion
        /// <summary>
        /// 最大的增益队列
        /// </summary>
        public int MaxEnhanceQueues
        {
            get { return m_MaxEnhanceQueues; }
            set
            {
                if ( value < 0 )
                    return;
                else
                    m_MaxEnhanceQueues = value;
            }
        }

        #endregion

        #region zh-CHS MaxDiminishQueues属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private int m_MaxDiminishQueues = int.MaxValue;
        #endregion
        /// <summary>
        /// 最大的减益队列
        /// </summary>
        public int MaxDiminishQueues
        {
            get { return m_MaxDiminishQueues; }
            set
            {
                if ( value < 0 )
                    return;
                else
                    m_MaxDiminishQueues = value;
            }
        }

        #endregion

        #region zh-CHS MaxBothQueues属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private int m_MaxBothQueues = int.MaxValue;
        #endregion
        /// <summary>
        /// 最大的队列
        /// </summary>
        public int MaxBothQueues
        {
            get { return m_MaxBothQueues; }
            set
            {
                if ( value < 0 )
                    return;
                else
                    m_MaxBothQueues = value;
            }
        }

        #endregion

        #region zh-CHS MaxNoneQueues属性 | en Public Properties

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private int m_MaxNoneQueues = int.MaxValue;
        #endregion
        /// <summary>
        /// 最大的队列
        /// </summary>
        public int MaxNoneQueues
        {
            get { return m_MaxNoneQueues; }
            set
            {
                if ( value < 0 )
                    return;
                else
                    m_MaxNoneQueues = value;
            }
        }

        #endregion

        #endregion

        #region zh-CHS 共有方法 | en Public Methods

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private Dictionary<long, Aura> m_AllInOneAura = new Dictionary<long, Aura>( 24 );
        /// <summary>
        /// 
        /// </summary>
        private LinkedList<Aura> m_AllInOneLinkedList = new LinkedList<Aura>();
        /// <summary>
        /// 
        /// </summary>
        private ReaderWriterLockSlim m_LockAllInOne = new ReaderWriterLockSlim();
        #endregion

        #region zh-CHS 私有方法 | en Private Methods
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private int GetAuraCountInLock( AuraEffect auraEffect )
        {
            int iCount = 0;

            foreach ( var auraItem in m_AllInOneLinkedList )
            {
                if ( auraItem.AuraEffect == auraEffect )
                    iCount++;
            }

            return iCount;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="auraEffect"></param>
        /// <returns></returns>
        private int GetMaxQueues( AuraEffect auraEffect )
        {
            if ( auraEffect == AuraEffect.Enhance )
                return m_MaxEnhanceQueues;
            else if ( auraEffect == AuraEffect.Diminish )
                return m_MaxDiminishQueues;
            else if ( auraEffect == AuraEffect.Both )
                return m_MaxBothQueues;
            else if ( auraEffect == AuraEffect.None )
                return m_MaxNoneQueues;
            else
                return 0;
        }

        /// <summary>
        /// 去掉顶层的技能光环
        /// </summary>
        /// <param name="auraEffect"></param>
        /// <returns></returns>
        private Aura RemoveFirstAuraInLock( AuraEffect auraEffect )
        {
            Aura firstHighest = null;
            Aura firstNormal = null;
            Aura firstLowest = null;

            foreach ( var auraItem in m_AllInOneLinkedList )
            {
                if ( auraItem.AuraEffect == auraEffect )
                {
                    switch ( auraItem.AuraPriority )
                    {
                        case AuraPriority.Normal:
                            {
                                if ( firstNormal == null && auraItem.IsAllowRemove == true )
                                    firstNormal = auraItem;
                            }

                            break;
                        case AuraPriority.Highest:
                            {
                                if ( firstHighest == null && auraItem.IsAllowRemove == true )
                                    firstHighest = auraItem;
                            }

                            break;
                        case AuraPriority.Lowest:
                            {
                                if ( firstLowest == null && auraItem.IsAllowRemove == true )
                                    firstLowest = auraItem;
                            }

                            break;
                        default:
                            break;
                    }
                }
            }

            if ( firstLowest != null )
            {
                m_AllInOneLinkedList.Remove( firstLowest );

                return firstLowest;
            }
            else if ( firstNormal != null )
            {
                m_AllInOneLinkedList.Remove( firstNormal );

                return firstNormal;
            }
            else if ( firstHighest != null )
            {
                m_AllInOneLinkedList.Remove( firstHighest );

                return firstHighest;
            }
            else
                return null;
        }

        /// <summary>
        /// 去掉顶层的技能光环
        /// </summary>
        /// <returns></returns>
        private Aura RemoveFirstAuraInLock()
        {
            Aura firstHighest = null;
            Aura firstNormal = null;
            Aura firstLowest = null;

            foreach ( var auraItem in m_AllInOneLinkedList )
            {
                switch ( auraItem.AuraPriority )
                {
                    case AuraPriority.Normal:
                        {
                            if ( firstNormal == null && auraItem.IsAllowRemove == true )
                                firstNormal = auraItem;
                        }

                        break;
                    case AuraPriority.Highest:
                        {
                            if ( firstHighest == null && auraItem.IsAllowRemove == true )
                                firstHighest = auraItem;
                        }

                        break;
                    case AuraPriority.Lowest:
                        {
                            if ( firstLowest == null && auraItem.IsAllowRemove == true )
                                firstLowest = auraItem;
                        }

                        break;
                    default:
                        break;
                }
            }

            if ( firstLowest != null )
            {
                m_AllInOneLinkedList.Remove( firstLowest );

                return firstLowest;
            }
            else if ( firstNormal != null )
            {
                m_AllInOneLinkedList.Remove( firstNormal );

                return firstNormal;
            }
            else if ( firstHighest != null )
            {
                m_AllInOneLinkedList.Remove( firstHighest );

                return firstHighest;
            }
            else
                return null;
        }

        /// <summary>
        /// 排除已满的低优先级的技能光环
        /// </summary>
        /// <returns></returns>
        private bool ClearAllInOneQueuesInLock()
        {
            // 是否已满 查询全部的队列 排除已满的低优先级的技能光环
            while ( m_AllInOneLinkedList.Count >= m_MaxAllInOneQueues )
            {
                // 去掉最前的 和 优先级最低的
                Aura removeAura = RemoveFirstAuraInLock();
                if ( removeAura == null )
                    break;

                m_AllInOneAura.Remove( removeAura.Serial );

                // 移除光环的事件
                EventHandler<RemovingAuraCallEventArgs<Aura>> tempRemovingEventArgs = m_EventRemovingAura;
                if ( tempRemovingEventArgs != null )
                {
                    RemovingAuraCallEventArgs<Aura> eventArgs = new RemovingAuraCallEventArgs<Aura>( removeAura, this );
                    tempRemovingEventArgs( this, eventArgs );
                }

                // 停止光环
                removeAura.Stop();
                removeAura.Parent = null; // 需要后置

                EventHandler<RemovedAuraCallEventArgs<Aura>> tempRemovedEventArgs = m_EventRemovedAura;
                if ( tempRemovedEventArgs != null )
                {
                    RemovedAuraCallEventArgs<Aura> eventArgs = new RemovedAuraCallEventArgs<Aura>( removeAura, this );
                    tempRemovedEventArgs( this, eventArgs );
                }
            }

            // 检测 是否成功删除
            return m_AllInOneLinkedList.Count >= m_MaxAllInOneQueues ? false : true;
        }

        /// <summary>
        /// 排除已满的针对当前光环效果的技能光环
        /// </summary>
        /// <returns></returns>
        private bool ClearAuraEffectQueuesInLock( AuraEffect auraEffect )
        {
            // 如果已经满足 查询全部的队列 开始查询针对当前光环效果的队列
            int iMaxQueues = GetMaxQueues( auraEffect );
            int iAuraEffectCount = GetAuraCountInLock( auraEffect );

            // 是否已满
            while ( iAuraEffectCount >= iMaxQueues )
            {
                // 去掉最前的 和 优先级最低的
                Aura removeAura = RemoveFirstAuraInLock( auraEffect );
                if ( removeAura == null )
                    break;

                --iAuraEffectCount;
                m_AllInOneAura.Remove( removeAura.Serial );

                // 移除光环的事件
                EventHandler<RemovingAuraCallEventArgs<Aura>> tempRemovingEventArgs = m_EventRemovingAura;
                if ( tempRemovingEventArgs != null )
                {
                    RemovingAuraCallEventArgs<Aura> eventArgs = new RemovingAuraCallEventArgs<Aura>( removeAura, this );
                    tempRemovingEventArgs( this, eventArgs );
                }

                // 停止光环
                removeAura.Stop();
                removeAura.Parent = null; // 需要后置

                EventHandler<RemovedAuraCallEventArgs<Aura>> tempRemovedEventArgs = m_EventRemovedAura;
                if ( tempRemovedEventArgs != null )
                {
                    RemovedAuraCallEventArgs<Aura> eventArgs = new RemovedAuraCallEventArgs<Aura>( removeAura, this );
                    tempRemovedEventArgs( this, eventArgs );
                }
            }

            // 检测 是否成功删除
            return iAuraEffectCount >= iMaxQueues ? false : true;
        }
        #endregion

        /// <summary>
        /// 添加 光环
        /// </summary>
        /// <param name="auraId"></param>
        /// <param name="newAura"></param>
        /// <returns></returns>
        public bool AddAura( long auraId, Aura newAura )
        {
            if ( newAura == null )
                throw new ArgumentNullException( "newAura", "AuraCollection.AddAura(...) - newAura == null error!" );

            if ( newAura.Serial != auraId )
                throw new ArgumentNullException( "auraId", "AuraCollection.AddAura(...) - newAura.Serial != auraId error!" );

            bool bAddResult = true;
            m_LockAllInOne.EnterWriteLock();
            try
            {
                do
                {
                    // 是否已经包含
                    if ( m_AllInOneAura.ContainsKey( auraId ) == true )
                        break;

                    bAddResult = ClearAllInOneQueuesInLock();
                    if ( bAddResult == false )
                        break;

                    m_bIsValueChange = true; // 队列已经修改过

                    bAddResult = ClearAuraEffectQueuesInLock( newAura.AuraEffect );
                    if ( bAddResult == false )
                        break;

                    m_AllInOneLinkedList.AddLast( newAura );
                    m_AllInOneAura.Add( auraId, newAura ); // 添加到全局

                    // 添加光环的事件
                    EventHandler<AddingAuraCallEventArgs<Aura>> tempAddingEventArgs = m_EventAddingAura;
                    if ( tempAddingEventArgs != null )
                    {
                        AddingAuraCallEventArgs<Aura> eventArgs = new AddingAuraCallEventArgs<Aura>( newAura, this );
                        tempAddingEventArgs( this, eventArgs );
                    }

                    // 开始光环
                    newAura.Parent = this; // 需要前置
                    newAura.Start();

                    EventHandler<AddedAuraCallEventArgs<Aura>> tempAddedEventArgs = m_EventAddedAura;
                    if ( tempAddedEventArgs != null )
                    {
                        AddedAuraCallEventArgs<Aura> eventArgs = new AddedAuraCallEventArgs<Aura>( newAura, this );
                        tempAddedEventArgs( this, eventArgs );
                    }

                } while ( false );
            }
            finally
            {
                m_LockAllInOne.ExitWriteLock();
            }

            return bAddResult;
        }

        /// <summary>
        /// 如果有原来的光环，就顶替掉原来的光环，并把光环放在到原来的地方
        /// </summary>
        public bool AddOrReplaceAura( long auraId, Aura newAura )
        {
            if ( newAura == null )
                throw new ArgumentNullException( "newAura", "AuraCollection.AddOrReplaceAura(...) - newAura == null error!" );

            if ( newAura.Serial != auraId )
                throw new ArgumentNullException( "auraId", "AuraCollection.AddOrReplaceAura(...) - newAura.Serial != auraId error!" );

            bool bAddResult = true;
            m_LockAllInOne.EnterWriteLock();
            try
            {
                do
                {
                    // 是否已经包含
                    bool isContains = false;
                    Aura replaceAura = null;
                    if ( m_AllInOneAura.TryGetValue( auraId, out replaceAura ) == true )
                    {
                        if ( replaceAura == null )
                            throw new Exception( "AuraCollection.AddOrReplaceAura(...) - replaceAura == null error!" );

                        // 是否可替换
                        if ( replaceAura.IsAllowReplace == false ) // 不可替换
                            break;

                        isContains = true;
                    }

                    // 如果没有包含,等于添加
                    if ( isContains == false ) // 如果没有包含,就添加
                    {
                        bAddResult = ClearAllInOneQueuesInLock();
                        if ( bAddResult == false )
                            break;

                        m_bIsValueChange = true; // 队列已经修改过

                        bAddResult = ClearAuraEffectQueuesInLock( newAura.AuraEffect );
                        if ( bAddResult == false )
                            break;

                        m_AllInOneLinkedList.AddLast( newAura );
                        m_AllInOneAura.Add( auraId, newAura ); // 添加到全局
                    }
                    else // 否则,就替换
                    {
                        LinkedListNode<Aura> linkedListNode = m_AllInOneLinkedList.Find( replaceAura );
                        if ( linkedListNode == null )
                            throw new Exception( "AuraCollection.AddOrReplaceAura(...) - linkedListNode == null error!" );

                        // 开始移除光环
                        Aura removeAura = linkedListNode.Value;

                        // 移除光环的事件
                        EventHandler<RemovingAuraCallEventArgs<Aura>> tempRemovingEventArgs = m_EventRemovingAura;
                        if ( tempRemovingEventArgs != null )
                        {
                            RemovingAuraCallEventArgs<Aura> eventArgs = new RemovingAuraCallEventArgs<Aura>( removeAura, this );
                            tempRemovingEventArgs( this, eventArgs );
                        }

                        // 停止光环
                        removeAura.Stop();
                        removeAura.Parent = null; // 需要后置

                        EventHandler<RemovedAuraCallEventArgs<Aura>> tempRemovedEventArgs = m_EventRemovedAura;
                        if ( tempRemovedEventArgs != null )
                        {
                            RemovedAuraCallEventArgs<Aura> eventArgs = new RemovedAuraCallEventArgs<Aura>( removeAura, this );
                            tempRemovedEventArgs( this, eventArgs );
                        }

                        linkedListNode.Value = newAura;
                        m_AllInOneAura[auraId] = newAura;
                    }

                    // 添加光环的事件
                    EventHandler<AddingAuraCallEventArgs<Aura>> tempAddingEventArgs = m_EventAddingAura;
                    if ( tempAddingEventArgs != null )
                    {
                        AddingAuraCallEventArgs<Aura> eventArgs = new AddingAuraCallEventArgs<Aura>( newAura, this );
                        tempAddingEventArgs( this, eventArgs );
                    }

                    // 开始光环
                    newAura.Parent = this; // 需要前置
                    newAura.Start();

                    EventHandler<AddedAuraCallEventArgs<Aura>> tempAddedEventArgs = m_EventAddedAura;
                    if ( tempAddedEventArgs != null )
                    {
                        AddedAuraCallEventArgs<Aura> eventArgs = new AddedAuraCallEventArgs<Aura>( newAura, this );
                        tempAddedEventArgs( this, eventArgs );
                    }

                    m_bIsValueChange = true; // 队列已经修改过

                } while ( false );
            }
            finally
            {
                m_LockAllInOne.ExitWriteLock();
            }

            return bAddResult;
        }

        /// <summary>
        /// 如果有原来的光环，就删除掉原来的光环，并把光环添加到末尾
        /// </summary>
        public bool ReplaceAndSortAura( long auraId, Aura newAura )
        {
            if ( newAura == null )
                throw new ArgumentNullException( "newAura", "AuraCollection.ReplaceAndSortAura(...) - newAura == null error!" );

            if ( newAura.Serial != auraId )
                throw new ArgumentNullException( "auraId", "AuraCollection.ReplaceAndSortAura(...) - newAura.Serial != auraId error!" );

            bool bAddResult = true;
            m_LockAllInOne.EnterWriteLock();
            try
            {
                do
                {
                    // 是否已经包含
                    bool isContains = false;
                    Aura replaceAura = null;
                    if ( m_AllInOneAura.TryGetValue( auraId, out replaceAura ) == true )
                    {
                        if ( replaceAura == null )
                            throw new Exception( "AuraCollection.ReplaceAndSortAura(...) - replaceAura == null error!" );

                        // 是否可替换
                        if ( replaceAura.IsAllowReplace == false ) // 不可替换
                            break;

                        isContains = true;
                    }

                    if ( isContains == false ) // 如果没有包含,就添加
                    {
                        bAddResult = ClearAllInOneQueuesInLock();
                        if ( bAddResult == false )
                            break;

                        m_bIsValueChange = true; // 队列已经修改过

                        bAddResult = ClearAuraEffectQueuesInLock( newAura.AuraEffect );
                        if ( bAddResult == false )
                            break;

                        m_AllInOneLinkedList.AddLast( newAura );
                        m_AllInOneAura.Add( auraId, newAura );  // 添加到全局
                    }
                    else
                    {
                        // 开始移除光环
                        Aura removeAura = replaceAura;

                        // 移除光环的事件
                        EventHandler<RemovingAuraCallEventArgs<Aura>> tempRemovingEventArgs = m_EventRemovingAura;
                        if ( tempRemovingEventArgs != null )
                        {
                            RemovingAuraCallEventArgs<Aura> eventArgs = new RemovingAuraCallEventArgs<Aura>( removeAura, this );
                            tempRemovingEventArgs( this, eventArgs );
                        }

                        // 停止光环
                        removeAura.Stop();
                        removeAura.Parent = null; // 需要后置

                        EventHandler<RemovedAuraCallEventArgs<Aura>> tempRemovedEventArgs = m_EventRemovedAura;
                        if ( tempRemovedEventArgs != null )
                        {
                            RemovedAuraCallEventArgs<Aura> eventArgs = new RemovedAuraCallEventArgs<Aura>( removeAura, this );
                            tempRemovedEventArgs( this, eventArgs );
                        }

                        bool isRemove = m_AllInOneLinkedList.Remove( removeAura );
                        if ( isRemove == false )
                            throw new Exception( "AuraCollection.ReplaceAndSortAura(...) - isRemove == false error!" );

                        // 添加
                        m_AllInOneLinkedList.AddLast( newAura );
                        m_AllInOneAura[auraId] = newAura;
                    }

                    // 添加光环的事件
                    EventHandler<AddingAuraCallEventArgs<Aura>> tempAddingEventArgs = m_EventAddingAura;
                    if ( tempAddingEventArgs != null )
                    {
                        AddingAuraCallEventArgs<Aura> eventArgs = new AddingAuraCallEventArgs<Aura>( newAura, this );
                        tempAddingEventArgs( this, eventArgs );
                    }

                    // 开始光环
                    newAura.Parent = this; // 需要前置
                    newAura.Start();

                    EventHandler<AddedAuraCallEventArgs<Aura>> tempAddedEventArgs = m_EventAddedAura;
                    if ( tempAddedEventArgs != null )
                    {
                        AddedAuraCallEventArgs<Aura> eventArgs = new AddedAuraCallEventArgs<Aura>( newAura, this );
                        tempAddedEventArgs( this, eventArgs );
                    }

                    m_bIsValueChange = true; // 队列已经修改过

                } while ( false );
            }
            finally
            {
                m_LockAllInOne.ExitWriteLock();
            }

            return bAddResult;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="auraId"></param>
        public bool RemoveAura( long auraId )
        {
            bool resultBool = false;

            m_LockAllInOne.EnterWriteLock();
            try
            {
                Aura removeAura = null;
                if ( m_AllInOneAura.TryGetValue( auraId, out removeAura ) == true )
                {
                    if ( removeAura != null )
                    {
                        m_AllInOneAura.Remove( auraId );
                        resultBool = m_AllInOneLinkedList.Remove( removeAura );

                        // 移除光环的事件
                        EventHandler<RemovingAuraCallEventArgs<Aura>> tempRemovingEventArgs = m_EventRemovingAura;
                        if ( tempRemovingEventArgs != null )
                        {
                            RemovingAuraCallEventArgs<Aura> eventArgs = new RemovingAuraCallEventArgs<Aura>( removeAura, this );
                            tempRemovingEventArgs( this, eventArgs );
                        }

                        // 停止光环
                        removeAura.Stop();
                        removeAura.Parent = null; // 需要后置

                        EventHandler<RemovedAuraCallEventArgs<Aura>> tempRemovedEventArgs = m_EventRemovedAura;
                        if ( tempRemovedEventArgs != null )
                        {
                            RemovedAuraCallEventArgs<Aura> eventArgs = new RemovedAuraCallEventArgs<Aura>( removeAura, this );
                            tempRemovedEventArgs( this, eventArgs );
                        }

                        m_bIsValueChange = true; // 队列已经修改过
                    }
                }
            }
            finally
            {
                m_LockAllInOne.ExitWriteLock();
            }

            return resultBool;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="auraId"></param>
        public Aura FindAuraOnId( long auraId )
        {
            Aura aura = null;

            m_LockAllInOne.EnterReadLock();
            try
            {
                m_AllInOneAura.TryGetValue( auraId, out aura );
            }
            finally
            {
                m_LockAllInOne.ExitReadLock();
            }

            return aura;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="AuraT"></typeparam>
        /// <param name="auraId"></param>
        /// <returns></returns>
        public AuraT FindAuraOnId<AuraT>( long auraId ) where AuraT : Aura
        {
            Aura aura = FindAuraOnId( auraId );
            if ( aura == null )
                return null;
            else
                return aura as AuraT;
        }

        /// <summary>
        /// 
        /// </summary>
        public void Clear()
        {
            m_LockAllInOne.EnterWriteLock();
            try
            {
                foreach ( var removeAura in m_AllInOneLinkedList )
                {
                    // 移除光环的事件
                    EventHandler<RemovingAuraCallEventArgs<Aura>> tempRemovingEventArgs = m_EventRemovingAura;
                    if ( tempRemovingEventArgs != null )
                    {
                        RemovingAuraCallEventArgs<Aura> eventArgs = new RemovingAuraCallEventArgs<Aura>( removeAura, this );
                        tempRemovingEventArgs( this, eventArgs );
                    }

                    // 停止光环
                    removeAura.Stop();
                    removeAura.Parent = null; // 需要后置

                    EventHandler<RemovedAuraCallEventArgs<Aura>> tempRemovedEventArgs = m_EventRemovedAura;
                    if ( tempRemovedEventArgs != null )
                    {
                        RemovedAuraCallEventArgs<Aura> eventArgs = new RemovedAuraCallEventArgs<Aura>( removeAura, this );
                        tempRemovedEventArgs( this, eventArgs );
                    }
                }

                m_AllInOneAura.Clear();
                m_AllInOneLinkedList.Clear();

                // 修改完成
                m_AuraArray = s_ZeroAuraArray;

                m_bIsValueChange = false; // 队列已经修改完成
            }
            finally
            {
                m_LockAllInOne.ExitWriteLock();
            }
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private readonly static Aura[] s_ZeroAuraArray = new Aura[0];
        /// <summary>
        /// 
        /// </summary>
        private volatile Aura[] m_AuraArray = s_ZeroAuraArray;
        /// <summary>
        /// 
        /// </summary>
        private volatile bool m_bIsValueChange = true;
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public Aura[] ToArray()
        {
            if ( m_bIsValueChange == false )
                return m_AuraArray;

            m_LockAllInOne.EnterReadLock();
            try
            {
                if ( m_bIsValueChange == true )
                {
                    List<Aura> auraList = new List<Aura>( m_AllInOneLinkedList.Count );
                    foreach ( var aura in m_AllInOneLinkedList )
                        auraList.Add( aura );

                    m_AuraArray = auraList.ToArray();

                    m_bIsValueChange = false;
                }
            }
            finally
            {
                m_LockAllInOne.ExitReadLock();
            }

            return m_AuraArray;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="auraPriority"></param>
        /// <returns></returns>
        public Aura[] ToArray( AuraPriority auraPriority )
        {
            Aura[] auraArray = this.ToArray();

            List<Aura> auraList = new List<Aura>( auraArray.Length );

            for ( int iIndex = 0; iIndex < auraArray.Length; iIndex++ )
            {
                Aura aura = auraArray[iIndex];
                if ( aura == null )
                    continue;

                if ( aura.AuraPriority == auraPriority )
                    auraList.Add( aura );
            }

            return auraList.ToArray();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="auraEffect"></param>
        /// <returns></returns>
        public Aura[] ToArray( AuraEffect auraEffect )
        {
            Aura[] auraArray = this.ToArray();

            List<Aura> auraList = new List<Aura>( auraArray.Length );

            for ( int iIndex = 0; iIndex < auraArray.Length; iIndex++ )
            {
                Aura aura = auraArray[iIndex];
                if ( aura == null )
                    continue;
                
                if ( aura.AuraEffect == auraEffect )
                    auraList.Add( aura );
            }

            return auraList.ToArray();
        }

        #endregion

        #region zh-CHS 共有事件 | en Public Event

        #region zh-CHS AddAuraCallEventArgs事件 | en Public Event

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private EventHandler<AddingAuraCallEventArgs<Aura>> m_EventAddingAura;
        /// <summary>
        /// 
        /// </summary>
        private SpinLock m_LockEventAddingAura = new SpinLock();
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<AddingAuraCallEventArgs<Aura>> AddingAura
        {
            add
            {
                SpinLockEx.ReliableEnter( ref m_LockEventAddingAura );
                try
                {
                    m_EventAddingAura += value;
                }
                finally
                {
                    m_LockEventAddingAura.Exit();
                }
            }
            remove
            {
                SpinLockEx.ReliableEnter( ref m_LockEventAddingAura );
                try
                {
                    m_EventAddingAura -= value;
                }
                finally
                {
                    m_LockEventAddingAura.Exit();
                }
            }
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private EventHandler<AddedAuraCallEventArgs<Aura>> m_EventAddedAura;
        /// <summary>
        /// 
        /// </summary>
        private SpinLock m_LockEventAddedAura = new SpinLock();
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<AddedAuraCallEventArgs<Aura>> AddedAura
        {
            add
            {
                SpinLockEx.ReliableEnter( ref m_LockEventAddedAura );
                try
                {
                    m_EventAddedAura += value;
                }
                finally
                {
                    m_LockEventAddedAura.Exit();
                }
            }
            remove
            {
                SpinLockEx.ReliableEnter( ref m_LockEventAddedAura );
                try
                {
                    m_EventAddedAura -= value;
                }
                finally
                {
                    m_LockEventAddedAura.Exit();
                }
            }
        }
        #endregion

        #region zh-CHS RemoveAuraCallEventArgs事件 | en Public Event

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private EventHandler<RemovingAuraCallEventArgs<Aura>> m_EventRemovingAura;
        /// <summary>
        /// 
        /// </summary>
        private SpinLock m_LockEventRemovingAura = new SpinLock();
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<RemovingAuraCallEventArgs<Aura>> RemovingAura
        {
            add
            {
                SpinLockEx.ReliableEnter( ref m_LockEventRemovingAura );
                try
                {
                    m_EventRemovingAura += value;
                }
                finally
                {
                    m_LockEventRemovingAura.Exit();
                }
            }
            remove
            {
                SpinLockEx.ReliableEnter( ref m_LockEventRemovingAura );
                try
                {
                    m_EventRemovingAura -= value;
                }
                finally
                {
                    m_LockEventRemovingAura.Exit();
                }
            }
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private EventHandler<RemovedAuraCallEventArgs<Aura>> m_EventRemovedAura;
        /// <summary>
        /// 
        /// </summary>
        private SpinLock m_LockEventRemovedAura = new SpinLock();
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public event EventHandler<RemovedAuraCallEventArgs<Aura>> RemovedAura
        {
            add
            {
                SpinLockEx.ReliableEnter( ref m_LockEventRemovedAura );
                try
                {
                    m_EventRemovedAura += value;
                }
                finally
                {
                    m_LockEventRemovedAura.Exit();
                }
            }
            remove
            {
                SpinLockEx.ReliableEnter( ref m_LockEventRemovedAura );
                try
                {
                    m_EventRemovedAura -= value;
                }
                finally
                {
                    m_LockEventRemovedAura.Exit();
                }
            }
        }
        #endregion

        #endregion
    }
}
#endregion